package com.zcoj.codeSimilar.service.impl;

import com.zcoj.codeSimilar.pojo.DTO.CodeSimilar;
import com.zcoj.codeSimilar.service.CodeSimilarService;
import com.zcoj.codeSimilar.service.ExecuteCodeSimilarService;
import com.zcoj.pojo.Dto.Judge;
import com.zcoj.pojo.Vo.UserInfoVO;
import com.zcoj.service.UserService;
import com.zcoj.util.RedisCaches;
import com.zcoj.util.WinnowingCodeSimilarity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

/**
 * @author chenbin
 * @version 1.0
 * @description: TODO
 * @date 2023/8/5 12:42
 */
@Service
@Slf4j
public class ExecuteCodeSimilarServiceImpl implements ExecuteCodeSimilarService {

	@Autowired
	private CodeSimilarService codeSimilarService;

	@Autowired
	private  WinnowingCodeSimilarity winnowingCodeSimilar;

	@Autowired
	private UserService userService;

	@Autowired
	private RedisCaches redisCaches;

	@Override
	@Async("taskExecutor")
	public void contrastCode(Integer pid,Integer cid, List<Judge> judgeList) {
		log.info("进入contrastCode");
		//按照提交时间升序排列
		judgeList.sort(Comparator.comparing(Judge::getSubmitTime));
		List<CodeSimilar> codeSimilarList=new ArrayList<>();
		//已经对比队列
		List<Judge> contrastCodeList=new ArrayList<>();
		if(judgeList.size()>1){
			contrastCodeList.add(judgeList.get(0));
			for (int i = 1; i < judgeList.size(); i++) {

				Judge judge = judgeList.get(i);
				UserInfoVO userInfoByID = userService.getUserInfoByID(judge.getUid());
				CodeSimilar codeSimilar = new CodeSimilar();
				codeSimilar.setPid(pid)
						.setPName(judge.getPName())
						.setUid(judge.getUid())
						.setCid(cid)
						.setSid(judge.getSubmitId())
						.setCode(judge.getCode())
						.setSimilar(0D)
						.setStatus(0)
						.setUname(userInfoByID.getUsername())
						.setCreateTime(new Date());
				for (Judge judgeContrast : contrastCodeList) {
					if(judge.getUid().equals(judgeContrast.getUid())){
						continue;
					}
					if (!judge.getLanguage().equals(judgeContrast.getLanguage())){
						continue;
					}
					double similarity = winnowingCodeSimilar.Similarity(codeSimilar.getCode(), judgeContrast.getCode());
					if(similarity>codeSimilar.getSimilar()){
						UserInfoVO userInfoByID1 = userService.getUserInfoByID(judgeContrast.getUid());
						codeSimilar.setContrastSid(judgeContrast.getSubmitId())
								.setContrastUid(judgeContrast.getUid())
								.setContrastCode(judgeContrast.getCode())
								.setSimilar(similarity)
								.setContrastUname(userInfoByID1.getUsername())
								.setStatus(1);
					}
				}
				contrastCodeList.add(judge);
				codeSimilarList.add(codeSimilar);
			}
			//完成相似度检测,将相似度为0的数据删除，从后往前删除
			for (int i = codeSimilarList.size()-1; i >=0; i--) {
				CodeSimilar codeSimilar = codeSimilarList.get(i);
				if(codeSimilar.getSimilar().equals(0D)){
					codeSimilarList.remove(i);
					i--;
				}
			}
			//写入数据库
			for (CodeSimilar codeSimilar : codeSimilarList) {
			    codeSimilarService.insertCodeSimilar(codeSimilar);
			}

			//移除redis  cid缓存（防止重复提交）
			String codeSimilarityCidKey="codeSimilarityCidKey::"+cid;
			redisCaches.deleteObject(codeSimilarityCidKey);
		}

	}


}
